#include "sys_uart.h"
#include "sys_clock.h"
#include "sys_gpio.h"
#include "sys_delay.h"
#include "sys_cache.h"
#include "sys_interrupt.h"
#include "sys_timer.h"
#include "sys_sd.h"
#include "sys_mmu.h"
#include "diskio.h"
#include "ff.h"
#include "string.h"

#include "book_fount.h"
/*---------------------------------------------------
修改BUG
	2020-09-22
		1.取卡插卡复位启动正常，不取卡复位启动不正常。
			改正方法：SD_Hardware_Reset()硬件复位延时由1ms改为50ms。
		2.读卡速度慢问题，示波器测量读扇区与读扇区中间存在长延时。
			改正方法：sunxi_mmc_send_cmd()中两个1000us延时改为1us延时。
		3.TF卡格式化选择[分配单元大小为64KB]会加快FATFS的写入速度。
			因为单元64KB大小时FATFS会128扇区连续读写,对写速度影响比较大,读速度影响较小。
		
		FATFS读写
		------------------------------
		Write Count: 13,107,200 
		Write Time: 927 ms
		Write Speed: 13,807 KB/S
		------------------------------
		Read Count: 13,107,200 
		Read Time: 681 ms
		Read Speed: 18,795 KB/S
		------------------------------
	2020-10-11
		1.增加热插拔检测。SD初始化里发送CMD8后加一个10ms延时，不然会概率性初始化错误。		
	2021-02-01
		1.高速卡CPU模式读错误。修改PLL_PERIPH时钟读取不对的问题后正确。	
----------------------------------------------------*/

#define SD_DET 0  //=1卡检测使能	
/*---------------------------------------------------
---- main
---- main
----------------------------------------------------*/
#include "ILI9342.h"
#include "sys_lcd_conf.h"
#include "sys_lcd.h"
//-----------------------
#include "gui_draw.h"
#include "gui_draw_bmp.h"
#include "gui_draw_rgb565.h"
#include "gui_draw_argb8888.h"
void extract_zip_file(const char* zip_path, const char* output_path);
int miniz_main();
void extract_zip_file2(const char* zip_path, const char* output_path);
int extract_opf_from_epub(const char *epub_path );

__align(4) unsigned int LCDbuff[XSIZE_PHYS*YSIZE_PHYS];//显存

void GUI_Draw_RGB565_Test2(void){
    //设置画布
	  Set_Canvas((unsigned int *)LCDbuff,XSIZE_PHYS,YSIZE_PHYS,CMODE_RGB565);	
		GUI_Clear_RGB565(RGB565_BLACK);
		GUI_Draw_String_RGB565(10,10,"F1C100S",RGB565_GREEN,0,0,1);
}

int SDx=SD0;
#define BUFF_SIZE (1024*1024) //读写缓存大小
__align(4) u8 buff[BUFF_SIZE]={0};
FATFS fs;
int main(void)
{ 
#if SD_DET		
	int SDInit=0;
#endif	
  int i;
	UINT br;
	FIL fp1;
	DIR dp1;
  Sys_Clock_Init(408000000);
	sys_mmu_init();	
	Sys_Uart_Init(UART0,408000000,115200,0);
	sysprintf("\r\n\r\n\r\n");
	sysprintf("Sys_Start...\r\n");
	sysprintf("[2020-09-23]...\r\n");	
	sysprintf("Dram Init Size %d Mb.\r\n",32);	
	//定时器
  Timer1_Init();
    //===========================================
    for( i=0;i<=21;i++)GPIO_Congif(GPIOD,GPIO_Pin_0+i,GPIO_Mode_IN,GPIO_PuPd_NOPULL);
	delay_ms(10);
    //ili9342_init();	
    Sys_LCD_Init(XSIZE_PHYS,YSIZE_PHYS,(unsigned int *)LCDbuff,NULL);
    GUI_Draw_RGB565_Test2();
    //===================================================================
    GUI_Draw_String_RGB565(10,30,"sd test",RGB565_GREEN,0,0,1);
    if(f_mount(&fs,"0:",1)==0){
        GUI_Draw_String_RGB565(10,30+ 16*1,"f_mount OK",RGB565_GREEN,0,0,1);
        
        i=f_open(&fp1, "0:/PicS61234/2018.txt",FA_OPEN_ALWAYS|FA_WRITE|FA_READ);
        if(i==0){
            GUI_Draw_String_RGB565(10,30+ 16*2,"f_open OK",RGB565_GREEN,0,0,1);
            f_close(&fp1);	
        }
    }
    //extract_zip_file2("/dzs/sj.zip", "/dzs/tx.txt") ;
    extract_opf_from_epub("/dzs/sj.zip");
    GUI_Draw_String_RGB565(10,30+ 16*3,"zip_file OK",RGB565_GREEN,0,0,1);
    
    //miniz_main();
     
//    draw_string_for_sd_start( );    
//    draw_string_for_sd(50,100, 16,"12我1",RGB565_GREEN);
//    draw_string_for_sd_end();
    while(1){
    
    }
				

				
}

#include "miniz.h"

void extract_zip_file(const char* zip_path, const char* output_path) {
    static char num = 0;
    static char numx = 0;
    mz_zip_archive zip_archive;
    mz_zip_zero_struct(&zip_archive);

    // 打开 ZIP 文件
    if (!mz_zip_reader_init_file(&zip_archive, zip_path, 0)) {
        //printf("Failed to open ZIP file: %s\n", zip_path);
        return;
    }

    // 遍历 ZIP 文件中的所有条目
    for (mz_uint i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) {
        mz_zip_archive_file_stat file_stat;
        if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
            //printf("Failed to get file stat.\n");
            continue;
        }

        // 打印文件名
        //printf("Extracting: %s\n", file_stat.m_filename);
        
        GUI_Draw_String_RGB565(100+200*numx,0+ 16*num,file_stat.m_filename,RGB565_GREEN,0,0,1);
        num++;
        if(num >= 16){
            num = 0;
            numx++;
        }
        // 提取文件到指定路径
        if (!mz_zip_reader_extract_file_to_file(&zip_archive, file_stat.m_filename, output_path, 0)) {
            //printf("Failed to extract file: %s\n", file_stat.m_filename);
            continue;
        }
    }

    // 关闭 ZIP 文件
    mz_zip_reader_end(&zip_archive);
}

void extract_zip_file2(const char* zip_path, const char* output_path) {
    static char num = 0;
    static char numx = 0;
    char buffer[4096] = {0};
    size_t pSize;
    mz_zip_archive zip_archive;
    mz_zip_zero_struct(&zip_archive);

    // 打开 ZIP 文件
    if (!mz_zip_reader_init_file(&zip_archive, zip_path, 0)) {
        //printf("Failed to open ZIP file: %s\n", zip_path);
        return;
    }

    // 遍历 ZIP 文件中的所有条目
    for (mz_uint i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) {
        mz_zip_archive_file_stat file_stat;
        if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
            //printf("Failed to get file stat.\n");
            continue;
        }

        // 打印文件名
        //printf("Extracting: %s\n", file_stat.m_filename);
        
        // 检查文件名是否是 OPF 文件
        if (strstr(file_stat.m_filename, "content.opf") != NULL) {
            GUI_Draw_String_RGB565(100+200*0,0+ 16*0,file_stat.m_filename,RGB565_GREEN,0,0,1);
            pSize = file_stat.m_uncomp_size;
            
            mz_uint file_index = mz_zip_reader_locate_file(&zip_archive, file_stat.m_filename, NULL, 0);
            //mz_zip_reader_extract_to_mem(&zip_archive, file_index, buffer, file_stat.m_uncomp_size, 0);
            // 提取 OPF 文件
            //void *file_data = mz_zip_reader_extract_to_heap(&zip_archive, i, &pSize, 0);
            //mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags)
            mz_zip_reader_extract_file_to_mem(&zip_archive,file_stat.m_filename,buffer,pSize,0);
//            if (!file_data) {
//               // printf("Failed to extract file: %s\n", file_stat.m_filename);
//                continue;
//            }
            sysprintf("buffer pSize = %d\n",pSize);
            for(int i = 0; i < 100;i++){
                sysprintf(" %d=",buffer[i]);	
            }
            
            //buffer[80] = 0;
            GUI_Draw_String_RGB565(10 ,150,&buffer[3],RGB565_GREEN,0,0,1);
            //free(file_data);
        }
        
        
        
        // 提取文件到指定路径
        if (!mz_zip_reader_extract_file_to_file(&zip_archive, file_stat.m_filename, output_path, 0)) {
            //printf("Failed to extract file: %s\n", file_stat.m_filename);
            continue;
        }
    }

    // 关闭 ZIP 文件
    mz_zip_reader_end(&zip_archive);
}

int miniz_main() {
    mz_zip_archive zip_archive;
    mz_zip_zero_struct(&zip_archive);

    // 打开 ZIP 文件
    if (!mz_zip_reader_init_file(&zip_archive, "/dzs/sj.zip", 0)) {
        //printf("Failed to open ZIP file.\n");
        return -1;
    }

    // 查找 ZIP 文件中的目标文件
    const char* target_filename = "OEBPS/content.opf";
    mz_uint file_index = mz_zip_reader_locate_file(&zip_archive, target_filename, NULL, 0);
//    if (file_index == MZ_UINT_MAX) {
//        //printf("Failed to locate file: %s\n", target_filename);
//        mz_zip_reader_end(&zip_archive);
//        return -1;
//    }

    // 获取文件信息
    mz_zip_archive_file_stat file_stat;
    if (!mz_zip_reader_file_stat(&zip_archive, file_index, &file_stat)) {
        sysprintf("Failed to get file information.\n");
        mz_zip_reader_end(&zip_archive);
        return -1;
    }

    // 分配缓冲区以存储文件内容
    char* buffer = (char*)malloc(file_stat.m_uncomp_size);
    if (!buffer) {
        sysprintf("Memory allocation failed.\n");
        mz_zip_reader_end(&zip_archive);
        return -1;
    }

    // 读取文件内容到缓冲区
    if (!mz_zip_reader_extract_to_mem(&zip_archive, file_index, buffer, file_stat.m_uncomp_size, 0)) {
        sysprintf("Failed to extract file content.\n");
        free(buffer);
        mz_zip_reader_end(&zip_archive);
        return -1;
    }

    // 输出文件内容
    sysprintf("File content:\n%s\n", buffer);
    
    for(int i = 0; i < 100;i++){
                sysprintf(" %d=",buffer[i]);	
            }

    // 清理资源
    free(buffer);
    mz_zip_reader_end(&zip_archive);

    return 0;
}
#define BUFFER_SIZE 4096
void my_printf(char *str){
    //sysprintf(str);
}
int miniz_main2() {
    mz_zip_archive zip_archive;
    mz_zip_zero_struct(&zip_archive);

    // 打开 EPUB 文件
    if (!mz_zip_reader_init_file(&zip_archive, "/dzs/dsj.epub", 0)) {
        //printf("Failed to open EPUB file.\n");
        return -1;
    }
    
    // 查找 content.opf 文件
    mz_zip_archive_file_stat file_stat;
    if (!mz_zip_reader_file_stat(&zip_archive, mz_zip_reader_locate_file(&zip_archive, "OEBPS/content.opf", NULL, 0), &file_stat)) {
        //printf("Failed to locate content.opf file.\n");
        mz_zip_reader_end(&zip_archive);
        return -1;
    }

    // 读取 content.opf 文件内容
    char* buffer = (char*)malloc(file_stat.m_uncomp_size);
    if (!buffer) {
        //printf("Memory allocation failed.\n");
        mz_zip_reader_end(&zip_archive);
        return -1;
    }

    if (!mz_zip_reader_extract_file_to_mem(&zip_archive, "OEBPS/content.opf", buffer, file_stat.m_uncomp_size, 0)) {
        //printf("Failed to extract content.opf file.\n");
        free(buffer);
        mz_zip_reader_end(&zip_archive);
        return -1;
    }
GUI_Clear_RGB565(RGB565_BLACK);
    // 处理 content.opf 文件内容（例如使用 TinyXML2 解析 XML）
    //printf("Content of content.opf:\n%s\n", buffer);
    sysprintf("Content of content.opf:\n%s\n", buffer);
    buffer[40] = 0;
    
    GUI_Draw_String_RGB565(10 ,150,buffer,RGB565_GREEN,0,0,1);
    GUI_Draw_String_RGB565(10 ,150,"1",RGB565_GREEN,0,0,1);
    // 清理资源
    free(buffer);
    mz_zip_reader_end(&zip_archive);

    return 0;
}

//====================
// 解压 EPUB 文件并查找 OPF 文件

int extract_opf_from_epub(const char *epub_path ) {
    // 打开 EPUB 文件
    FIL file;
    FILINFO fno;  // 文件信息结构体
    uint32_t rd_len; 
    size_t pSize;    
    //FIL *fp = 
    f_open(&file,epub_path, FA_READ);

    
     f_stat(epub_path, &fno);
    long file_size = fno.fsize ;

    // 读取文件内容到内存
    void *zip_data = malloc(file_size);
    f_read(&file,zip_data,   file_size, &rd_len);
    f_close(&file);

    // 打开 ZIP 文件
    mz_zip_archive zip_archive;
    memset(&zip_archive, 0, sizeof(zip_archive));

    if (!mz_zip_reader_init_mem(&zip_archive, zip_data, file_size, 0)) {
        //printf("Failed to open ZIP archive\n");
        free(zip_data);
        return -1;
    }

    // 遍历 ZIP 文件中的文件
    int num_files = mz_zip_reader_get_num_files(&zip_archive);
    for (int i = 0; i < num_files; i++) {
        mz_zip_archive_file_stat file_stat;
        if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
            //printf("Failed to read file stat for file %d\n", i);
            continue;
        }

        // 检查文件名是否是 OPF 文件
        if (strstr(file_stat.m_filename, "content.opf") != NULL) {
            //printf("Found OPF file: %s\n", file_stat.m_filename);
            pSize = file_stat.m_uncomp_size;
            // 提取 OPF 文件
            void *file_data = mz_zip_reader_extract_to_heap(&zip_archive, i, &pSize, 0);
            if (!file_data) {
               // printf("Failed to extract file: %s\n", file_stat.m_filename);
                continue;
            }
            
            sysprintf("file_data\n %s\n",file_data);
            char* buffer = file_data;
            for(int i = 0; i < 100;i++){
                sysprintf(" %d=",buffer[i]);
            }                           

            free(file_data);
        }
    }

    // 清理
    mz_zip_reader_end(&zip_archive);
    free(zip_data);

    return 0;
}






